package com.chuangshu.chuangshuteam.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chuangshu.chuangshuteam.config.BaseContext;
import com.chuangshu.chuangshuteam.dto.FileMetadataDto;
import com.chuangshu.chuangshuteam.dto.PostDTO;
import com.chuangshu.chuangshuteam.dto.Result;
import com.chuangshu.chuangshuteam.entity.BusinessKey;
import com.chuangshu.chuangshuteam.entity.Comments;
import com.chuangshu.chuangshuteam.entity.FileInfo;
import com.chuangshu.chuangshuteam.entity.Likes;
import com.chuangshu.chuangshuteam.entity.PostTags;
import com.chuangshu.chuangshuteam.entity.Posts;
import com.chuangshu.chuangshuteam.entity.Tags;
import com.chuangshu.chuangshuteam.mapper.FileInfoMapper;
import com.chuangshu.chuangshuteam.service.CommentsService;
import com.chuangshu.chuangshuteam.service.LikesService;
import com.chuangshu.chuangshuteam.service.PostTagsService;
import com.chuangshu.chuangshuteam.service.PostsService;
import com.chuangshu.chuangshuteam.service.TagsService;
import com.chuangshu.chuangshuteam.util.File;
import com.chuangshu.chuangshuteam.vo.PostVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author k
 * @since 2025-09-21
 */
@RestController
@RequestMapping("/posts")
public class PostsController {
    
    @Autowired
    private PostsService postsService;
    
    @Autowired
    private TagsService tagsService;
    
    @Autowired
    private PostTagsService postTagsService;
    
    @Autowired
    private FileInfoMapper fileInfoMapper;
    
    @Autowired
    private File fileUtil;
    
    @Autowired
    private LikesService likesService;
    
    @Autowired
    private CommentsService commentsService;
    
    /**
     * 创建帖子
     * @param postDTO 帖子数据传输对象
     * @return 结果
     */
    @PostMapping
    public Result createPost(@RequestBody PostDTO postDTO) {
        // 参数校验
        if (postDTO.getTitle() == null || postDTO.getTitle().trim().isEmpty()) {
            return Result.fail("帖子标题不能为空");
        }
        if (postDTO.getContent() == null || postDTO.getContent().trim().isEmpty()) {
            return Result.fail("帖子内容不能为空");
        }
       
        // 创建帖子实体
        Posts post = new Posts();
        BeanUtils.copyProperties(postDTO, post);
        post.setAuthorId(BaseContext.getCurrentId());
        post.setCreatedAt(LocalDateTime.now());
        post.setUpdatedAt(LocalDateTime.now());

        // 保存帖子
        postsService.save(post);
        
        // 处理标签
        handlePostTags(post.getId(), postDTO.getTags());
        
        // 处理文件
        handlePostFiles(post.getId(), postDTO.getFiles());
        
        return Result.ok(post);
    }
    
    /**
     * 上传文件
     * @param file 文件
     * @return 文件信息
     */
    @PostMapping("/upload")
    public Result uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            // 检查文件类型
            String contentType = file.getContentType();
            if (contentType == null || !fileUtil.isAllowedFileType(contentType)) {
                return Result.fail("不支持的文件类型");
            }
            
            // 获取文件字节
            byte[] fileBytes = file.getBytes();
            
            // 获取存储桶名称
            String bucketName = fileUtil.getFileType(contentType);
            
            // 上传文件
            String fileUrl = fileUtil.uploadFile(fileBytes, file.getOriginalFilename(), contentType, bucketName);
            
            // 构造返回数据
            FileMetadataDto fileMetadataDto = new FileMetadataDto();
            fileMetadataDto.setFileName(file.getOriginalFilename());
            fileMetadataDto.setFilePath(fileUrl);
            fileMetadataDto.setFileType(contentType);
            fileMetadataDto.setFileSize(file.getSize());
            
            return Result.ok(fileMetadataDto);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail("文件上传失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取帖子列表（分页）
     * @param page 页码
     * @param size 每页大小
     * @return 帖子列表
     */
    @GetMapping
    public Result getPosts(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer size) {
        
        Page<Posts> postsPage = new Page<>(page, size);
        LambdaQueryWrapper<Posts> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Posts::getCreatedAt);
        
        Page<Posts> result = postsService.page(postsPage, queryWrapper);
        
        // 转换为VO对象并添加点赞信息
        List<PostVO> postVOs = result.getRecords().stream().map(this::convertToVO).collect(Collectors.toList());
        
        Page<PostVO> voPage = new Page<>(page, size, result.getTotal());
        voPage.setRecords(postVOs);
        voPage.setPages(result.getPages());
        voPage.setTotal(result.getTotal());
        
        return Result.ok(voPage);
    }
    
    /**
     * 获取当前用户发布的帖子列表（分页）
     * @param page 页码
     * @param size 每页大小
     * @return 帖子列表
     */
    @GetMapping("/my")
    public Result getMyPosts(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer size) {
        
        Long userId = BaseContext.getCurrentId();
        Page<Posts> postsPage = new Page<>(page, size);
        LambdaQueryWrapper<Posts> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Posts::getAuthorId, userId)
                .orderByDesc(Posts::getCreatedAt);
        
        Page<Posts> result = postsService.page(postsPage, queryWrapper);
        
        // 转换为VO对象并添加点赞信息
        List<PostVO> postVOs = result.getRecords().stream().map(this::convertToVO).collect(Collectors.toList());
        
        Page<PostVO> voPage = new Page<>(page, size, result.getTotal());
        voPage.setRecords(postVOs);
        voPage.setPages(result.getPages());
        voPage.setTotal(result.getTotal());
        
        return Result.ok(voPage);
    }
    
    /**
     * 根据ID获取帖子详情
     * @param id 帖子ID
     * @return 帖子详情
     */
    @GetMapping("/{id}")
    public Result getPostById(@PathVariable Long id) {
        Posts post = postsService.getById(id);
        if (post == null) {
            return Result.fail("帖子不存在");
        }
        
        // 构造返回数据
        PostVO postVO = convertToVO(post);
        
        return Result.ok(postVO);
    }
    
    /**
     * 更新帖子
     * @param id 帖子ID
     * @param postDTO 帖子数据传输对象
     * @return 结果
     */
    @PutMapping("/{id}")
    public Result updatePost(@PathVariable Long id, @RequestBody PostDTO postDTO) {
        // 检查帖子是否存在
        Posts existingPost = postsService.getById(id);
        if (existingPost == null) {
            return Result.fail("帖子不存在");
        }
        
        // 检查权限（只有作者可以更新）
        if (!existingPost.getAuthorId().equals(BaseContext.getCurrentId())) {
            return Result.fail("没有权限更新该帖子");
        }
        
        // 更新帖子
        Posts post = new Posts();
        BeanUtils.copyProperties(postDTO, post);
        post.setId(id);
        post.setAuthorId(existingPost.getAuthorId());
        post.setCreatedAt(existingPost.getCreatedAt());
        post.setUpdatedAt(LocalDateTime.now());
        
        postsService.updateById(post);
        
        // 处理标签
        handlePostTags(id, postDTO.getTags());
        
        // 处理文件
        handlePostFiles(id, postDTO.getFiles());
        
        return Result.ok(post);
    }
    
    /**
     * 删除帖子
     * @param id 帖子ID
     * @return 结果
     */
    @DeleteMapping("/{id}")
    public Result deletePost(@PathVariable Long id) {
        // 检查帖子是否存在
        Posts existingPost = postsService.getById(id);
        if (existingPost == null) {
            return Result.fail("帖子不存在");
        }
        
        // 检查权限（只有作者可以删除）
        if (!existingPost.getAuthorId().equals(BaseContext.getCurrentId())) {
            return Result.fail("没有权限删除该帖子");
        }
        
        // 删除帖子关联的文件
        List<FileInfo> fileInfos = fileInfoMapper.selectByBusinessIdAndType(id, BusinessKey.POSTS_ID);
        for (FileInfo fileInfo : fileInfos) {
            fileUtil.deleteByUrl(fileInfo.getFilePath());
        }
        fileInfoMapper.deleteByBusinessIdAndType(id, BusinessKey.POSTS_ID);
        
        // 删除帖子的点赞记录
        LambdaQueryWrapper<Likes> likesQueryWrapper = new LambdaQueryWrapper<>();
        likesQueryWrapper.eq(Likes::getLikableId, id).eq(Likes::getLikableType, "posts");
        likesService.remove(likesQueryWrapper);
        
        // 删除帖子的评论
        LambdaQueryWrapper<Comments> commentsQueryWrapper = new LambdaQueryWrapper<>();
        commentsQueryWrapper.eq(Comments::getPostId, id);
        commentsService.remove(commentsQueryWrapper);
        
        // 删除帖子
        postsService.removeById(id);
        
        // 删除帖子与标签的关联
        LambdaQueryWrapper<PostTags> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PostTags::getPostId, id);
        postTagsService.remove(queryWrapper);
        
        return Result.ok("帖子删除成功");
    }
    
    /**
     * 处理帖子标签关联
     * @param postId 帖子ID
     * @param tagNames 标签名称列表
     */
    private void handlePostTags(Long postId, List<String> tagNames) {
        if (tagNames == null || tagNames.isEmpty()) {
            return;
        }
        
        // 删除原有的标签关联
        LambdaQueryWrapper<PostTags> deleteWrapper = new LambdaQueryWrapper<>();
        deleteWrapper.eq(PostTags::getPostId, postId);
        postTagsService.remove(deleteWrapper);
        
        // 获取或创建标签
        List<Tags> tags = new ArrayList<>();
        for (String tagName : tagNames) {
            LambdaQueryWrapper<Tags> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Tags::getName, tagName);
            Tags tag = tagsService.getOne(queryWrapper);
            
            if (tag == null) {
                // 标签不存在，创建新标签
                tag = new Tags();
                tag.setName(tagName);
                tagsService.save(tag);
            }
            
            tags.add(tag);
        }
        
        // 创建新的标签关联
        List<PostTags> postTagsList = tags.stream().map(tag -> {
            PostTags postTags = new PostTags();
            postTags.setPostId(postId);
            postTags.setTagId(tag.getId());
            return postTags;
        }).collect(Collectors.toList());
        
        postTagsService.saveBatch(postTagsList);
    }
    
    /**
     * 处理帖子文件关联
     * @param postId 帖子ID
     * @param files 文件信息列表
     */
    private void handlePostFiles(Long postId, List<FileMetadataDto> files) {
        if (files == null || files.isEmpty()) {
            return;
        }
        
        // 删除原有的文件关联
        fileInfoMapper.deleteByBusinessIdAndType(postId, BusinessKey.POSTS_ID);
        
        // 创建新的文件关联
        List<FileInfo> fileInfos = files.stream().map(fileDto -> {
            FileInfo fileInfo = new FileInfo();
            fileInfo.setBusinessId(postId);
            fileInfo.setBusinessType(BusinessKey.POSTS_ID);
            fileInfo.setFileName(fileDto.getFileName());
            fileInfo.setFilePath(fileDto.getFilePath());
            fileInfo.setFileType(fileDto.getFileType());
            fileInfo.setFileSize(fileDto.getFileSize());
            fileInfo.setCreatedBy(BaseContext.getCurrentId());
            return fileInfo;
        }).collect(Collectors.toList());
        
        for (FileInfo fileInfo : fileInfos) {
            fileInfoMapper.insert(fileInfo);
        }
    }
    
    /**
     * 获取帖子的标签列表
     * @param postId 帖子ID
     * @return 标签名称列表
     */
    private List<String> getPostTags(Long postId) {
        // 查询帖子与标签的关联
        LambdaQueryWrapper<PostTags> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PostTags::getPostId, postId);
        List<PostTags> postTagsList = postTagsService.list(queryWrapper);
        
        if (postTagsList.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 获取标签ID列表
        List<Long> tagIds = postTagsList.stream()
                .map(PostTags::getTagId)
                .collect(Collectors.toList());
        
        // 查询标签
        List<Tags> tags = tagsService.listByIds(tagIds);
        
        // 返回标签名称列表
        return tags.stream()
                .map(Tags::getName)
                .collect(Collectors.toList());
    }
    
    /**
     * 获取帖子的文件列表
     * @param postId 帖子ID
     * @return 文件信息列表
     */
    private List<FileMetadataDto> getPostFiles(Long postId) {
        // 查询帖子关联的文件
        List<FileInfo> fileInfos = fileInfoMapper.selectByBusinessIdAndType(postId, BusinessKey.POSTS_ID);
        
        // 转换为DTO
        return fileInfos.stream().map(fileInfo -> {
            FileMetadataDto fileMetadataDto = new FileMetadataDto();
            BeanUtils.copyProperties(fileInfo, fileMetadataDto);
            return fileMetadataDto;
        }).collect(Collectors.toList());
    }
    
    /**
     * 将Posts实体转换为PostVO视图对象
     * @param post 帖子实体
     * @return PostVO视图对象
     */
    private PostVO convertToVO(Posts post) {
        if (post == null) {
            return null;
        }
        
        PostVO postVO = new PostVO();
        BeanUtils.copyProperties(post, postVO);
        
        // 设置标签
        postVO.setTags(getPostTagEntities(post.getId()));
        
        // 设置文件
        postVO.setFiles(getPostFiles(post.getId()));
        
        // 设置点赞状态
        Long userId = BaseContext.getCurrentId();
        LambdaQueryWrapper<Likes> likeQueryWrapper = new LambdaQueryWrapper<>();
        likeQueryWrapper.eq(Likes::getUserId, userId)
                .eq(Likes::getLikableId, post.getId())
                .eq(Likes::getLikableType, "posts");
        postVO.setIsLiked(likesService.count(likeQueryWrapper) > 0);
        
        // 设置点赞数
        LambdaQueryWrapper<Likes> countQueryWrapper = new LambdaQueryWrapper<>();
        countQueryWrapper.eq(Likes::getLikableId, post.getId())
                .eq(Likes::getLikableType, "posts");
        postVO.setLikeCount(likesService.count(countQueryWrapper));
        
        // 设置评论数
        LambdaQueryWrapper<Comments> commentQueryWrapper = new LambdaQueryWrapper<>();
        commentQueryWrapper.eq(Comments::getPostId, post.getId())
                .isNull(Comments::getDeletedAt);
        postVO.setCommentCount(commentsService.count(commentQueryWrapper));
        
        return postVO;
    }
    
    /**
     * 获取帖子的标签实体列表
     * @param postId 帖子ID
     * @return 标签实体列表
     */
    private List<Tags> getPostTagEntities(Long postId) {
        // 查询帖子与标签的关联
        LambdaQueryWrapper<PostTags> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PostTags::getPostId, postId);
        List<PostTags> postTagsList = postTagsService.list(queryWrapper);
        
        if (postTagsList.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 获取标签ID列表
        List<Long> tagIds = postTagsList.stream()
                .map(PostTags::getTagId)
                .collect(Collectors.toList());
        
        // 查询标签
        return tagsService.listByIds(tagIds);
    }
}